use std::collections::HashMap;

use once_cell::sync::Lazy;

pub static PRIMITIVE_TYPES: Lazy<HashMap<&'static str, &'static str>> = Lazy::new(|| HashMap::from_iter(
    vec![
        ("void",    "V"),
        ("boolean", "Z"),
        ("byte",    "B"),
        ("short" ,  "S"),
        ("int",     "I"),
        ("long",    "J"),
        ("char",    "C"),
        ("float",   "F"),
        ("double",  "D"),
    ].into_iter()
));

pub fn get_array_class_name(class_name: String) -> String {
    String::from("[") + &to_descriptor(&class_name)
}

fn to_descriptor<'a>(class_name: &str) -> String {
    if class_name.starts_with("[") {
        return class_name.to_string();
    }
    if let Some(d) = PRIMITIVE_TYPES.get(class_name) {
        return d.to_string();
    }
    "L".to_string() + class_name + ";"
    
}

pub fn get_component_class_name(class_name: String) -> String {
    if class_name.starts_with("[") {
        let component_type_descriptor = &class_name[1..];
        return to_class_name(component_type_descriptor);
    }
    panic!("Not array: {}", class_name);
}

pub fn to_class_name(descriptor: &str) -> String {
    // array
    if descriptor.starts_with("[") {
        return descriptor.to_string();
    }
    // object
    if descriptor.starts_with("L") {
        let len = descriptor.len();
        // 取消开头L与末尾分号(;)
        return descriptor[1..len-1].to_string();
    }
    for (class_name, d) in PRIMITIVE_TYPES.iter() {
        if *d == descriptor {
            return class_name.to_string()
        }
    }
    panic!("Invalid descriptor: {}", descriptor);
}